from rlinterface import Interface

from rlcore import Colour
from rlkbinput import Key, KeyboardInput

import curses

class CursesInterface (Interface): # Assumed to be initialized exactly one time and to be the sole initializer/deinitializer of curses.
	def __init__(self, layout, autodeinitialize = True, standardSize = (80,25) ):
		Interface.__init__(self, layout = layout, standardSize = standardSize )
		self.screen = curses.initscr()
		self.height, self.width = self.screen.getmaxyx()
		curses.start_color()
		curses.curs_set( 0 )
		curses.noecho()
		self.screen.leaveok( 1 )
		self.screen.keypad( 1 )
		self.screen.timeout( 50 )
		self.autodeinitialize = autodeinitialize
		primitiveColours = Colour.black, Colour.blue, Colour.cyan, Colour.green, Colour.magenta, Colour.red, Colour.white, Colour.yellow = curses.COLOR_BLACK, curses.COLOR_BLUE, curses.COLOR_CYAN, curses.COLOR_GREEN, curses.COLOR_MAGENTA, curses.COLOR_RED, curses.COLOR_WHITE, curses.COLOR_YELLOW
		self.pairs = {}
		if len( primitiveColours )**2 <= curses.COLOR_PAIRS:
			j = 1
			for fg in range(len(primitiveColours)):
				for bg in range(len(primitiveColours)):
					if fg == bg and fg != Colour.white: continue
					curses.init_pair( j, fg, bg )
					self.pairs[ (fg,bg) ] = curses.color_pair( j )
					j += 1
		else:
			raise NeedFancierTerminal( "COLOR_PAIRS is too low, value of %d required" % (len(primitiveColours)**2) )
		self.inputTranslationTable = {
			curses.KEY_UP: Key.North,
			curses.KEY_DOWN: Key.South,
			curses.KEY_LEFT: Key.West,
			curses.KEY_RIGHT: Key.East,
			curses.KEY_HOME: Key.Home,
			curses.KEY_PPAGE: Key.PageUp,
			curses.KEY_END: Key.End,
			curses.KEY_NPAGE: Key.PageDown,
		}
	def start(self):
		self.layout()
	def __del__(self):
		if self.autodeinitialize: # May want to turn this off to see error messages, for users who know how to fix broken terminals.
			self.quit()
	def quit(self):
		if not curses.isendwin():
			curses.endwin()
	def makeAttributes(self, glyph):
		try: rv = self.pairs[ (glyph.fgColour, glyph.bgColour) ]
		except KeyError: raise ProgrammerGoof( "illegal colour pair %s requested" % repr( (glyph.fgColour, glyph.bgColour) ) )
		if "bold" in glyph.effects: rv |= curses.A_BOLD
		if "dim" in glyph.effects: rv |= curses.A_DIM
		return rv
	def move(self, x, y):
		self.screen.move( y, x )
	def put(self, glyph):
		self.screen.addch( glyph.char, self.makeAttributes(glyph) )
	def putString(self, text, protoglyph, limit = None):
		if limit != None and limit <= 0: return
		if limit:
			self.screen.addnstr( text, limit, self.makeAttributes( protoglyph ) )
		else:
			self.screen.addstr( text, self.makeAttributes( protoglyph ) )
	def putBlank(self):
		self.screen.addch( ' ', self.pairs[ (curses.COLOR_WHITE, curses.COLOR_BLACK) ] )
	def putBlanks(self, n):
		for i in range(n):
			self.screen.addch( ' ', self.pairs[ (curses.COLOR_WHITE, curses.COLOR_BLACK) ] )
	def clear(self):
		self.screen.erase()
		self.screen.refresh()
	def refresh(self):
		self.screen.erase()
		self.drawElements()
		self.screen.refresh()
	def handleResize(self):
		self.height, self.width = self.screen.getmaxyx()
		self.layout()
		self.refresh()
	def getInput(self):
		rv = None
		while rv == None:
			keyNo = self.screen.getch()
			curses.flushinp()
			if keyNo == curses.ERR:
				continue
			if keyNo == curses.KEY_RESIZE:	
				self.handleResize()
				continue
			if keyNo >= 0 and keyNo <= 255:
				rv = KeyboardInput( ascii = keyNo )
			elif self.inputTranslationTable.has_key( keyNo ):
				rv = KeyboardInput( desc = self.inputTranslationTable[ keyNo ] )
		return rv
